#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include <signal.h>
#include <sys/time.h>

#define BIRD '@'    //@表示小鸟
#define BLANK ' '   //空格表示空格
#define PIPE '+'   //+表示管道
				   //
int bird_y,bird_x;    //小鸟坐标
/*定义关于管道的结构体*/
typedef struct Pipe{
	int x;  //列坐标
	int y;  //横坐标
	struct Pipe *next;
}Pipe_node,*Pipe_list;
Pipe_list head,tail;   //头尾结点
					   
/*创建链表*/
void creat_list(){
	int i;
	Pipe_list p,new;
	head = (Pipe_list)malloc(sizeof(Pipe_node));
	head->next = NULL;
	p = head;

	for(i=0;i<6;i++){
		new = (Pipe_list)malloc(sizeof(Pipe_node));
		new->x = (i+1)*20;
		new->y = rand()%11+5;  //管道5-15行
		new->next = NULL;
		p->next = new;
		p = new;
	}
	tail = p;
}
/*显示管道*/
void show_pipe(){
	Pipe_list p;
	int i,j;
	p = head->next;
	attron(COLOR_PAIR(2));
	while(p){
		for(i=p->x;i<p->x+10;i++){
			/*创建上半部分管道*/
			for(j=0;j<p->y;j++){
				move(j,i);
				addch(PIPE);
			}
			/*创建下半部分管道*/
			for(j=p->y+5;j<25;j++){
				move(j,i);
				addch(PIPE);
			}
		}
		refresh();
		p = p->next;
	}
	attroff(COLOR_PAIR(2));
}
/*清除管道*/
void clear_pipe(){
	Pipe_list p;
	int i,j;
	p = head->next;
	while(p){
		for(i=p->x;i<p->x+10;i++){
			/*清除上半部分管道*/
			for(j=0;j<p->y;j++){
				move(j,i);
				addch(BLANK);
			}
			/*清除下半部分管道*/
			for(j=p->y+5;j<25;j++){
				move(j,i);
				addch(BLANK);
			}
		}
		refresh();
		p = p->next;
	}

}
/*移动管道*/
void move_pipe(){
	Pipe_list p;
	p = head->next;
	while(p){
		p->x--;
		p = p->next;
	}
}
/*初始化Ncurses库*/
void init_curses(){
	initscr();	//进入curses模式
	curs_set(0);   //禁止光标显示
	noecho();	//禁止输入字符显示
	keypad(stdscr,1);	//允许功能键在当前窗口使用
	start_color();		//启动颜色机制
	init_pair(1,COLOR_WHITE,COLOR_RED);   //设置小鸟颜色，字体白色，背景红色
	init_pair(2,COLOR_WHITE,COLOR_GREEN);   //设置管道颜色
	
}
/*设置定时器，参数为毫秒（ms）*/
int set_timer(int ms_t){
	struct itimerval timer;
	long t_sec,t_usec;
	int ret;
	t_sec = ms_t / 1000;  //s
	t_usec = (ms_t % 1000) * 1000;  //us
	
	timer.it_value.tv_sec = t_sec;
	timer.it_value.tv_usec = t_usec;  //首次启动定时值
	timer.it_interval.tv_sec = t_sec;
	timer.it_interval.tv_usec = t_usec;  //之后每次启动的定时值
	
	ret = setitimer(ITIMER_REAL,&timer,NULL);    //启动定时器
	
	return ret;
}
/*显示小鸟*/
void show_bird(){
	attron(COLOR_PAIR(1));
	move(bird_y,bird_x);
	addch(BIRD);
	refresh();
	attroff(COLOR_PAIR(1));
}
/*清除小鸟*/
void clear_bird(){
	move(bird_y,bird_x);
	addch(BLANK);
	refresh();

}
/*移动小鸟*/
void move_bird(){
	char key;
	while(1){
		key = getch();
		if(key==' '){
			clear_bird();
			bird_y--;
			show_bird();
			/*游戏结束判断*/
			if((char)inch()==PIPE){
				set_timer(0);   //停止定时
				endwin();    //退出模式
				exit(0);    //结束程序
			}
		}
	}
}

void handler(int sig){
	Pipe_list p,new;
	//小鸟下落
	clear_bird();
	bird_y++;
	show_bird();
	//管道的循环创建
	p = head->next;
	if(p->x==0){
		int i,j;
		head->next = p->next;
		for(i=p->x;i<p->x+10;i++){
			/*清除上半部分管道*/
			for(j=0;j<p->y;j++){
				move(j,i);
				addch(BLANK);
			}
			/*清除下半部分管道*/
			for(j=p->y+5;j<25;j++){
				move(j,i);
				addch(BLANK);
			}
			refresh();
		}
		free(p);
		new = (Pipe_list)malloc(sizeof(Pipe_node));
		new->x = tail->x+20;
		new->y = rand()%11+5;
		new->next = NULL;
		tail->next = new;
		tail = new;
	}
	/*游戏结束判断*/
	if((char)inch()==PIPE){
		set_timer(0);   //停止定时
		endwin();    //退出模式
		exit(0);    //结束程序			
	}
	//管道左移
	clear_pipe();
	move_pipe();
	show_pipe();
}

/*主函数*/
int main(int argc,const char *argv[]){
	bird_y = 15; //行
	bird_x = 15; //列
	init_curses();
	signal(SIGALRM,handler);
	set_timer(500);  //定时时间为500毫秒
	srand(time(0));  //随机种子：每次启动的管道长度不一样
	creat_list();
	show_pipe();
	show_bird();
	move_bird();
	return 0;
}
